﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo00
{

    struct PersonStruct
    {
        public string name;
        public int telephone;
        public string address;
    }
    class Program
    {
        static void Main(string[] args)
        {
            //定义一个结构体，名为PersonStruct，有三个成员变量：姓名、电话、地址，
            //在主方法中，创建一个PersonStruct结构体对象p1，为p1的成员变量赋值。
            //再声明一个PersonStruct结构体变量p2，把p1赋值给p2，改变p2的姓名，打印p1的内容。

            PersonStruct P1 = new PersonStruct();
            P1.name = "阿刁";
            P1.telephone = 12306;
            P1.address = "潍坊";

            Console.WriteLine("赋值前:");
            Console.WriteLine("P1的姓名:" + P1.name + "---" + "P1的电话:" + P1.telephone + "---" + "P1的地址:" + P1.address);

            PersonStruct P2 = new PersonStruct();
            P2 = P1;
            P2.name = "阿肆";

            Console.WriteLine("赋值后:");
            Console.WriteLine("P1的姓名:" + P1.name + "---" + "P1的电话:" + P1.telephone + "---" +"P1的地址:" + P1.address);
            Console.WriteLine("P2的姓名:" + P2.name + "---" + "P2的电话:" + P2.telephone + "---" + "P2的地址:" + P2.address);

            //定义一个类，名为PersonClass，有三个成员变量：姓名、电话、地址，
            //在主方法中，创建一个PersonClass对象p3，为p3的成员变量赋值。
            //再声明一个PersonClass变量p4，把p3赋值给p4，改变p4的姓名，打印p3的内容。


            PersonClass P3 = new PersonClass();
            P3.name = "阿彪";
            P3.telephone = 12123;
            P3.address = "廊坊";

            Console.WriteLine("赋值前:");
            Console.WriteLine("P3的姓名:" + P3.name + "---" + "P3的电话:" + P3.telephone + "---" + "P3的地址:" + P3.address);

            PersonClass P4 = new PersonClass();
            P4 = P3;
            P4.name = "阿叼";

            Console.WriteLine("赋值后:");
            Console.WriteLine("P3的姓名:" + P3.name + "---" + "P3的电话:" + P3.telephone + "---" + "P3的地址:" + P3.address);
            Console.WriteLine("P4的姓名:" + P4.name + "---" + "P4的电话:" + P4.telephone + "---" + "P4的地址:" + P4.address);

            //观察打印结果，并在在注释中，说下你对此的认识（它们为什么会这样？）
            //区别:赋值后, P1.name != P2.name; P3.name == P4.name。

            //Struct方法和类(Class)方法的区别:
            //struct是值类型，创建一个struct类型的实例被分配在栈上。class是引用类型，创建一个class类型实例被分配在托管堆上。
            //● 类是引用类型，struct是值类型
            //● 在托管堆上创建类的实例，在栈上创建struct实例
            //● 类实例的赋值，赋的是引用地址，struct实例的赋值，赋的是值
            //● 类作为参数类型传递，传递的是引用地址，struct作为参数类型传递，传递的是值
            //● 类没有默认无参构造函数，struct有默认无参构造函数
            //● 类支持继承，struct不支持继承
            //● 类偏向于"面向对象",用于复杂、大型数据，struct偏向于"简单值"，比如小于16字节，结构简单
            //● 类的成员很容易赋初值，很难给struct类型成员赋初值
            //● 类的实例只能通过new SomeClass()来创建，struct类型的实例既可以通过new SomeStruct()来创建，也可以通过SomeStruct myStruct;来创建


            //何时使用struct，何时使用class?

            //在多数情况下，推荐使用class类，因为无论是类的赋值、作为参数类型传递，还是返回类的实例，实际拷贝的是托管堆上引用地址，也就大概4个字节，这非常有助于性能的提升。

            //而作为struct类型，无论是赋值，作为参数类型传递，还是返回struct类型实例，是完全拷贝，会占用栈上的空间。根据Microsoft's Value Type Recommendations，在如下情况下，推荐使用struct：

            //● 小于16个字节
            //● 偏向于值，是简单数据，而不是偏向于"面向对象"
            //● 希望值不可变

        }
    }
}
